package pl.enigmatic.reflection;

public class NestedPropertyGetter implements Getter {

	private final Getter[] chain;
	private final PropertyPath path;

	public NestedPropertyGetter(Class<?> cls, final PropertyPath path) throws Exception {
		this.path = path;
		chain = new Getter[path.getDepth()];
		for (int i = 0; i < path.getDepth(); i++) {
			final String property = path.get(i);
			try {
				chain[i] = new SimpleGetter(cls, property);
			} catch (final Exception e0) {
				try {
					chain[i] = new PublicPropertyGetter(cls, property);
				} catch (final Exception e1) {
					chain[i] = createGetter(cls, property);
				}
			}
			if (chain[i] == null) { throw new Exception(String.format("No getter found for property '%1$s' in class '%2$s'", property, cls.getName())); }
			cls = chain[i].getType();
		}
	}

	protected Getter createGetter(final Class<?> cls, final String property) {
		return null;
	}

	@Override
	public Object get(final Object target) {
		Object res = target;
		int i = 0;
		while (i < chain.length && res != null) {
			res = chain[i++].get(res);
		}
		return res;
	}

	@Override
	public Class<?> getType() {
		return chain[chain.length - 1].getType();
	}

	@Override
	public PropertyPath getPath() {
		return path;
	}

}
